import com.vmware.vim25.*;
import com.vmware.vim25.mo.Folder;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ManagedEntity;
import com.vmware.vim25.mo.PerformanceManager;
import com.vmware.vim25.mo.ServiceInstance;

import java.net.URL;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * VirtualMachine CPUMemory Created by vixuan-008 on 2015/4/20.
 * http://blog.csdn.net/zhouzhiwengang/article/details/45150113
 */
public class VM {

	/**
	 * Created by vixuan-008 on 2015/4/20.
	 */

	private ServiceInstance instance = null;
	private InventoryNavigator inventoryNavigator = null;

	public static void main(String[] args) throws Exception{
		String[] temp = new String[]{"https://10.16.2.59/sdk","root","vmware"};

		ServiceInstance si = new ServiceInstance(new URL(temp[0]), temp[1], temp[2], true);
		Folder rootFolder = si.getRootFolder();
		PerformanceManager perfMgr = si.getPerformanceManager();
		
		ManagedEntity[]  vm=  new InventoryNavigator(rootFolder).searchManagedEntities("VirtualMachine");
		for(ManagedEntity v:vm){
			Integer t = perfMgr.queryPerfProviderSummary(v).getRefreshRate();
			
			List list = new VM().getVMCPUPerByTimeRange(v.getName(),si,t,null);
			
			System.out.println(list);
		}
		
		
		
		
		
	}
	public List getVMCPUPerByTimeRange(String vcomName,
			ServiceInstance serviceInstance, int timeRange, String instanceName)
			throws Exception {
		List result = new ArrayList();
		instance = serviceInstance;
		inventoryNavigator = new InventoryNavigator(instance.getRootFolder());
		ManagedEntity obj = inventoryNavigator.searchManagedEntity(
				"VirtualMachine", vcomName);
		if (null == obj)
			throw new Exception();
		com.vmware.vim25.mo.VirtualMachine vm = (com.vmware.vim25.mo.VirtualMachine) obj;
		PerformanceManager pfMgr = instance.getPerformanceManager();
		PerfMetricId[] pfMtIds = pfMgr.queryAvailablePerfMetric(vm, null, null,
				timeRange);
		List<Map> contids = getCpuUsageAndUsageMhzCounterIds(pfMgr, vm,
				timeRange);
		if (null != contids && contids.size() > 0) {
			int[] counterIds = new int[pfMtIds.length];
			int iLabel = 0;
			for (PerfMetricId pfMt : pfMtIds) {
				int contId = pfMt.getCounterId();
				counterIds[iLabel++] = contId;
			}
			List<Map> instances = new ArrayList<Map>();
			for (PerfMetricId mtId : pfMtIds) {
				int counterId = mtId.getCounterId();

				for (Map m : contids) {
					Integer cntId = (Integer) m.get("counterId");
					String groupName = (String) m.get("groupName");
					String targetName = (String) m.get("targetName");
					if (counterId == cntId
							&& (null == instanceName || (null != instanceName && mtId
									.getInstance().equals(instanceName)))) {
						Map mm = new HashMap();
						mm.put("counterId", cntId);
						mm.put("instanceId", mtId.getInstance());
						mm.put("groupName", groupName);
						mm.put("targetName", targetName);
						instances.add(mm);
					}

				}

			}

			for (int i = 0; i < instances.size(); i++) {
				PerfMetricId[] cpuCores = new PerfMetricId[1];
				Map m = instances.get(i);
				cpuCores[0] = new PerfMetricId();
				cpuCores[0].setCounterId((Integer) m.get("counterId"));
				cpuCores[0].setInstance((String) m.get("instanceId"));
				PerfQuerySpec qSpec = createPerfQuerySpec(vm, cpuCores, 1,
						timeRange);
				PerfEntityMetricBase[] pValues = pfMgr
						.queryPerf(new PerfQuerySpec[] { qSpec });
				Map resultM = new HashMap();
				String values = "";
				String lables = "";
				String point = "" + m.get("targetName");
				PerfMetricSeriesCSV[] csvs = null;
				String name = "" + m.get("targetName") + ""
						+ m.get("groupName");
				for (int j = 0; j < pValues.length; j++) {
					PerfEntityMetricCSV csvValue = (PerfEntityMetricCSV) pValues[j];

					csvs = csvValue.getValue();
					lables = csvValue.getSampleInfoCSV();
					for (int k = 0; k < csvs.length; k++) {
						values += csvs[k].getValue() + ",";
					}

				}
				resultM.put("name", name);
				resultM.put("values", values);
				resultM.put("lables", lables);
				resultM.put("instance", instanceName);
				resultM.put("point", point);
				resultM.put("csvs", csvs);
				result.add(resultM);
			}
		}

		return result;
	}

	public PerfQuerySpec createPerfQuerySpec(ManagedEntity me,
			PerfMetricId[] metricIds, int maxSample, int interval) {
		PerfQuerySpec qSpec = new PerfQuerySpec();
		qSpec.setEntity(me.getMOR());
		// set the maximum of metrics to be return
		// only appropriate in real-time performance collecting
		qSpec.setMaxSample(new Integer(maxSample));
		qSpec.setMetricId(metricIds);
		// optionally you can set format as "normal"
		qSpec.setFormat("csv");
		// qSpec.setFormat("normal");
		// set the interval to the refresh rate for the entity
		qSpec.setIntervalId(new Integer(interval));

		return qSpec;
	}

	private List<Map> getCpuUsageAndUsageMhzCounterIds(
			PerformanceManager pfMgr, ManagedEntity managedEntity, Integer point)
			throws RemoteException {
		List<Map> result = new ArrayList<Map>();
		PerfMetricId[] pfMtIds = pfMgr.queryAvailablePerfMetric(managedEntity,
				null, null, point);
		if (null != pfMtIds && pfMtIds.length > 0) {
			int[] counterIds = new int[pfMtIds.length];
			int iLabel = 0;
			for (PerfMetricId pfMt : pfMtIds) {
				int contId = pfMt.getCounterId();
				counterIds[iLabel++] = contId;
			}

			PerfCounterInfo[] pfContinfos = pfMgr.queryPerfCounter(counterIds);
			List<String> gpList = new ArrayList<String>();
			for (int i = 0; i < pfContinfos.length; i++) {
				String strName = pfContinfos[i].getNameInfo().getKey();
				String groupName = pfContinfos[i].getGroupInfo().getKey();
				if (null != groupName && groupName.equals("cpu")) {
					if (null != strName && strName.equals("usage")
							|| strName.equals("usagemhz")) {
						if (result.size() > 0) {
							boolean flag = true;
							for (Map mm : result) {
								Integer key = (Integer) mm.get("counterId");
								if (key.equals(pfContinfos[i].getKey()))
									flag = false;
							}
							if (flag) {
								Map m = new HashMap();
								m.put("counterId", counterIds[i]);
								m.put("groupName", groupName);
								m.put("targetName", strName);
								result.add(m);
							}

						} else {
							Map m = new HashMap();

							m.put("counterId", counterIds[i]);
							m.put("groupName", groupName);
							m.put("targetName", strName);
							result.add(m);
						}
					}
				}
			}
		}
		return result;
	}

	public List getVMMemPerByTimeRange(String vcomName,
			ServiceInstance serviceInstance, int timeRange, String instanceName)
			throws Exception {
		List result = new ArrayList();
		instance = serviceInstance;
		inventoryNavigator = new InventoryNavigator(instance.getRootFolder());
		ManagedEntity obj = inventoryNavigator.searchManagedEntity(
				"VirtualMachine", vcomName);
		if (null == obj)
			throw new Exception();
		com.vmware.vim25.mo.VirtualMachine vm = (com.vmware.vim25.mo.VirtualMachine) obj;
		PerformanceManager pfMgr = instance.getPerformanceManager();
		PerfProviderSummary summary = pfMgr.queryPerfProviderSummary(vm);
		PerfInterval[] rfRates = pfMgr.getHistoricalInterval();
		PerfMetricId[] pfMtIds = pfMgr.queryAvailablePerfMetric(vm, null, null,
				timeRange);
		List<Map> contids = getMemUsageAndOverHeadCounterIds(pfMgr, vm,
				timeRange);
		if (null != contids && contids.size() > 0) {
			int[] counterIds = new int[pfMtIds.length];
			int iLabel = 0;
			for (PerfMetricId pfMt : pfMtIds) {
				int contId = pfMt.getCounterId();
				counterIds[iLabel++] = contId;
			}
			List<Map> instances = new ArrayList<Map>();
			for (PerfMetricId mtId : pfMtIds) {
				int counterId = mtId.getCounterId();

				for (Map m : contids) {
					Integer cntId = (Integer) m.get("counterId");
					String groupName = (String) m.get("groupName");
					String targetName = (String) m.get("targetName");
					if (counterId == cntId
							&& (null == instanceName || (null != instanceName && mtId
									.getInstance().equals(instanceName)))) {
						Map mm = new HashMap();
						mm.put("counterId", cntId);
						mm.put("instanceId", mtId.getInstance());
						mm.put("groupName", groupName);
						mm.put("targetName", targetName);
						instances.add(mm);
					}

				}

			}

			for (int i = 0; i < instances.size(); i++) {
				PerfMetricId[] cpuCores = new PerfMetricId[1];
				Map m = instances.get(i);
				cpuCores[0] = new PerfMetricId();
				cpuCores[0].setCounterId((Integer) m.get("counterId"));
				cpuCores[0].setInstance((String) m.get("instanceId"));
				PerfQuerySpec qSpec = createPerfQuerySpec(vm, cpuCores, 1,
						timeRange);
				PerfEntityMetricBase[] pValues = pfMgr
						.queryPerf(new PerfQuerySpec[] { qSpec });
				Map resultM = new HashMap();
				String values = "";
				String lables = "";
				String point = "" + m.get("targetName");
				PerfMetricSeriesCSV[] csvs = null;
				String name = "" + m.get("targetName") + ""
						+ m.get("groupName");
				for (int j = 0; j < pValues.length; j++) {
					PerfEntityMetricCSV csvValue = (PerfEntityMetricCSV) pValues[j];

					csvs = csvValue.getValue();
					lables = csvValue.getSampleInfoCSV();
					for (int k = 0; k < csvs.length; k++) {
						values += csvs[k].getValue() + ",";
					}

				}
				resultM.put("name", name);
				resultM.put("values", values);
				resultM.put("lables", lables);
				resultM.put("instance", instanceName);
				resultM.put("point", point);
				resultM.put("csvs", csvs);
				result.add(resultM);
			}
		}

		return result;
	}

	private List<Map> getMemUsageAndOverHeadCounterIds(
			PerformanceManager pfMgr, ManagedEntity managedEntity, Integer point)
			throws RemoteException {
		List<Map> result = new ArrayList<Map>();
		PerfMetricId[] pfMtIds = pfMgr.queryAvailablePerfMetric(managedEntity,
				null, null, point);
		if (null != pfMtIds && pfMtIds.length > 0) {
			int[] counterIds = new int[pfMtIds.length];
			int iLabel = 0;
			for (PerfMetricId pfMt : pfMtIds) {
				int contId = pfMt.getCounterId();
				counterIds[iLabel++] = contId;
			}

			PerfCounterInfo[] pfContinfos = pfMgr.queryPerfCounter(counterIds);
			List<String> gpList = new ArrayList<String>();
			for (int i = 0; i < pfContinfos.length; i++) {
				String strName = pfContinfos[i].getNameInfo().getKey();
				String groupName = pfContinfos[i].getGroupInfo().getKey();
				if (null != groupName && groupName.equals("mem")) {
					if (null != strName && strName.equals("usage")
							|| strName.equals("consumed")) {
						if (result.size() > 0) {
							boolean flag = true;
							for (Map mm : result) {
								Integer key = (Integer) mm.get("counterId");
								if (key.equals(pfContinfos[i].getKey()))
									flag = false;
							}
							if (flag) {
								Map m = new HashMap();
								m.put("counterId", counterIds[i]);
								m.put("groupName", groupName);
								m.put("targetName", strName);
								result.add(m);
							}

						} else {
							Map m = new HashMap();

							m.put("counterId", counterIds[i]);
							m.put("groupName", groupName);
							m.put("targetName", strName);
							result.add(m);
						}
					}
				}
			}
		}
		return result;
	}
}